package cn.com.open.itembank.controller;

import cn.com.open.itembank.common.enums.AnswerType;
import cn.com.open.itembank.common.enums.ImportType;
import cn.com.open.itembank.common.enums.InputType;
import cn.com.open.itembank.common.enums.SourceType;
import cn.com.open.itembank.dto.*;
import cn.com.open.itembank.entity.CourseItemBank;
import cn.com.open.itembank.exception.PoiException;
import cn.com.open.itembank.service.ImportService;
import cn.com.open.itembank.service.ItemService;
import net.lingala.zip4j.exception.ZipException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Map;

/**
 * Created by lucky on 2017/9/13.
 */
@RestController
@RequestMapping(value = "/itembank")
public class ItemBankController {

    @Autowired
    private ItemService service;
    @Autowired
    private ImportService importService;

    //region 判断题库和试题是否存在关系

    /**
     * 判断题库和试题是否存在关系.
     *
     * @param itembankId 题库id
     * @param id         试题id
     * @return the boolean
     */
    @GetMapping(value = "/{itembankId}/question/{id}/relation")
    public boolean checkItemBankQuestionRelation(@PathVariable("itembankId") String itembankId, @PathVariable(value = "id") String id) {
        return service.checkItemBankQuestionRelation(itembankId, id);
    }
    //endregion

    //region 获取指定题库下指定试题

    /**
     * 获取指定题库下指定试题信息(paper用).
     *
     * @param itembankId    题库id
     * @param id            试题id
     * @param includeAnswer 是否包含答案
     * @return 试题模型 item for paper
     */
    @GetMapping(value = "/{itembankId}/question/{id}/condition")
    public QuestionModel getItemForPaper(@PathVariable("itembankId") String itembankId, @PathVariable(value = "id") String id,
                                         @RequestParam boolean includeAnswer) {
        return service.getItemBankQuestionForPaper(itembankId, id, includeAnswer);
    }

    /**
     * 获取指定题库下指定试题全部信息.
     *
     * @param itembankId 题库id
     * @param id         试题id
     * @return 试题模型 full item
     */
    @GetMapping(value = "/{itembankId}/question/{id}")
    public ReturnModel getFullItem(@PathVariable("itembankId") String itembankId, @PathVariable(value = "id") String id) {
        return service.getItemBankQuestion(itembankId, id, AnswerType.ALL);
    }

    /**
     * 获取指定题库下指定试题答案信息.
     *
     * @param itembankId 题库id
     * @param id         试题id
     * @return 试题答案模型 item answer
     */
    @GetMapping(value = "/{itembankId}/question/{id}/answer")
    public ReturnModel getItemAnswer(@PathVariable("itembankId") String itembankId, @PathVariable(value = "id") String id) {

        return service.getItemBankQuestion(itembankId, id, AnswerType.ANSWER);
    }

    /**
     * 获取指定题库下指定试题不含答案的信息.
     *
     * @param itembankId 题库id
     * @param id         试题id
     * @return 试题无答案模型 item without answer
     */
    @GetMapping(value = "/{itembankId}/question/{id}/withoutanswer")
    public ReturnModel getItemWithoutAnswer(@PathVariable("itembankId") String itembankId, @PathVariable(value = "id") String id) {

        return service.getItemBankQuestion(itembankId, id, AnswerType.NOANSWER);
    }
    //endregion

    //region 随机获取指定题库指定题型指定数量的试题集合

    /**
     * 随机获取指定题库指定题型指定数量的试题集合.
     * 历史接口：openapi/v3/ItemBank/{cid}/type/{tid}/GetRandomQuestions
     *
     * @param itembankId     题库id
     * @param questionTypeId 题型id
     * @param cnt            获取数量
     * @return 试题id集合 random questions by item bank id and q type
     */
    @GetMapping(value = "/{itembankId}/questiontype/{questionTypeId}/question/random")
    public ReturnModel getRandomQuestionsByItemBankIdAndQType(@PathVariable(value = "itembankId") String itembankId,
                                                              @PathVariable(value = "questionTypeId") String questionTypeId,
                                                              @RequestParam(value = "cnt") int cnt) {
        return service.getRandomQuestionsByItemBankIdAndQType(itembankId, questionTypeId, cnt);
    }
    //endregion

    //region 根据题库id获取指定题库下试题按照题型，难度，应用类别的数量统计列表

    /**
     * 根据题库id获取指定题库下试题按照题型，难度，应用类别的数量统计列表.
     * 历史接口：openapi/v3/ItemBank/{itembankId}/GetQuestionCount
     *
     * @param itembankId 题库id
     * @return 数量统计列表 question stat by item bank id
     */
    @GetMapping(value = "/{itembankId}/question/stat/oes")
    public ReturnModel getQuestionStatByItemBankId(@PathVariable(value = "itembankId") String itembankId) {
        return service.getQuestionStatByItemBankId(itembankId);
    }
    //endregion

    //region 根据题库id获取指定题库下试题按照应用类别的数量统计列表

    /**
     * 根据题库id获取指定题库下试题按照应用类别的数量统计列表.
     * 历史接口：/openapi/v3/Course/{courseId}/Question/GetQuestionCountByQuestionType
     *
     * @param itembankId 题库id
     * @return 数量统计列表 question stat for category by item bank id
     */
    @GetMapping(value = "/{itembankId}/question/category/stat")
    public ReturnModel getQuestionStatForCategoryByItemBankId(@PathVariable(value = "itembankId") String itembankId) {
        return service.getQuestionStatForCategoryByItemBankId(itembankId);
    }
    //endregion

    //region 根据题库id获取指定题库下指定题型的试题按照给定的章节,应用类别统计的难中易三档题数列表

    /**
     * 根据题库id获取指定题库下指定题型的试题按照给定的章节,应用类别统计的难中易三档题数列表.
     * 历史接口：/openapi/v3/ItemBank/{ItemBankId}/Question/ConditionCount
     * 撤销历史接口：/openapi/v3/Course/{CourseId}/Question/ConditionCountByCourseId
     *
     * @param itembankId 题库id
     * @param cntModel   统计参数模型
     * @return 数量统计列表 question difficulty stat by item bank id
     */
    @PostMapping(value = "/{itembankId}/question/difficulty/stat")
    public ReturnModel getQuestionDifficultyStatByItemBankId(@PathVariable(value = "itembankId") String itembankId, @RequestBody DifficultyCountModel cntModel) {
        return service.getQuestionDifficultyStatByItemBankId(itembankId, cntModel);
    }
    //endregion

    //region 新增试题

    /**
     * 新增试题（以itembankid为准替代模型对应数值）.
     *
     * @param itembankId    题库id
     * @param questionModel 试题录入模型
     * @param appKey        appkey
     * @param source        来源：0，内部；1，外部
     * @return the return model
     */
    @RequestMapping(value = "/{itembankId}/question", method = RequestMethod.POST, consumes = "application/json")
    public ReturnModel addQuestion(@PathVariable(value = "itembankId") String itembankId, @RequestBody QuestionModel questionModel,
                                   @RequestParam("appkey") String appKey, @RequestParam("source") int source) {
        questionModel.setI4(itembankId);

        return service.addQuestion(questionModel, source, SourceType.QUESTION.getIndex(), InputType.MANUALINPUT.getIndex(),
                ImportType.NONE.getIndex(), appKey);
    }
    //endregion

    //region 切换试题审核状态

    /**
     * 切换试题审核状态.
     * 历史接口：/openapi/v3/Question/{id}/check
     *
     * @param itembankId 题库id
     * @param id         试题id
     * @param appKey     appkey
     * @param isCheck    True，审核通过；False，取消审核
     * @return the return model
     */
    @PutMapping(value = "/{itembankId}/question/{id}/check")
    public ReturnModel updateCheckStatus(@PathVariable(value = "itembankId") String itembankId, @PathVariable(value = "id") String id,
                                         @RequestParam("appkey") String appKey, @RequestParam("isCheck") boolean isCheck) {
        return service.updateCheckStatus(itembankId, id, isCheck, appKey);
    }
    //endregion

    //region 切换试题停启用状态

    /**
     * 切换试题停启用状态.
     * 历史接口：/openapi/v3/Question/{id}/UpdateStatus
     *
     * @param itembankId 题库id
     * @param id         试题id
     * @param appKey     appkey
     * @return the return model
     */
    @PutMapping(value = "/{itembankId}/question/{id}/status")
    public ReturnModel updateStatus(@PathVariable(value = "itembankId") String itembankId, @PathVariable(value = "id") String id,
                                    @RequestParam("appkey") String appKey) {
        return service.updateStatus(itembankId, id, appKey);
    }
    //endregion

    //region 删除试题

    /**
     * 临时删除试题.
     *
     * @param itembankId 题库id
     * @param id         试题id
     * @param appKey     appkey
     * @return the return model
     */
    @DeleteMapping(value = "/{itembankId}/question/{id}")
    public ReturnModel deleteQuestion(@PathVariable(value = "itembankId") String itembankId, @PathVariable(value = "id") String id,
                                      @RequestParam("appkey") String appKey) {
        return service.deleteQuestion(itembankId, id, appKey);

    }

    /**
     * 批量临时删除试题.
     *
     * @param itembankId 题库id
     * @param idList     the id list
     * @param appKey     appkey
     * @return the return model
     */
    @PostMapping(value = "/{itembankId}/question/batchdelete")
    public ReturnModel deleteQuestionList(@PathVariable(value = "itembankId") String itembankId, @RequestBody IdentifierArray idList,
                                          @RequestParam("appkey") String appKey) {
        return service.deleteQuestionList(itembankId, idList.getIdList(), appKey);
    }

    /**
     * 恢复试题.
     *
     * @param itembankId 题库id
     * @param id         试题id
     * @param appKey     appkey
     * @return the return model
     */
    @PutMapping(value = "/{itembankId}/question/{id}/recover")
    public ReturnModel recover(@PathVariable(value = "itembankId") String itembankId, @PathVariable(value = "id") String id,
                               @RequestParam("appkey") String appKey) {
        return service.recover(itembankId, id, appKey);

    }

    /**
     * 批量恢复试题.
     *
     * @param itembankId 题库id
     * @param idList     the id list
     * @param appKey     appkey
     * @return the return model
     */
    @PostMapping(value = "/{itembankId}/question/batchrecover")
    public ReturnModel recoverList(@PathVariable(value = "itembankId") String itembankId, @RequestBody IdentifierArray idList,
                                   @RequestParam("appkey") String appKey) {
        return service.recoverList(itembankId, idList.getIdList(), appKey);
    }

    /**
     * 彻底删除试题.
     *
     * @param itembankId 题库id
     * @param id         试题id
     * @param appKey     appkey
     * @return the return model
     */
    @DeleteMapping(value = "/{itembankId}/question/{id}/remove")
    public ReturnModel removeQuestion(@PathVariable(value = "itembankId") String itembankId, @PathVariable(value = "id") String id,
                                      @RequestParam("appkey") String appKey) {

        return service.removeQuestion(itembankId, id, appKey);

    }

    /**
     * 批量彻底删除试题.
     *
     * @param itembankId 题库id
     * @param idList     the id list
     * @param appKey     appkey
     * @return the return model
     */
    @PostMapping(value = "/{itembankId}/question/batchremove")
    public ReturnModel removeQuestionList(@PathVariable(value = "itembankId") String itembankId, @RequestBody IdentifierArray idList,
                                          @RequestParam("appkey") String appKey) {
        return service.removeQuestionList(itembankId, idList.getIdList(), appKey);
    }
    //endregion

    //region 导出试题

    /**
     * 导出试题.
     *
     * @param itembankId 题库id
     * @return the return model
     */
    @PostMapping(value = "/{itembankId}/question/exportquestion")
    public ReturnModel exportQuestion(@PathVariable(value = "itembankId") String itembankId, @RequestBody FilterModelDto filterModelDto) throws PoiException, ZipException, IOException {

        return service.exportQuestion(filterModelDto);
    }
    //endregion

    //region 试题列表

    /**
     * 试题列表.
     *
     * @param itembankId 题库id
     * @return the return model
     */
    @PostMapping(value = "/{itembankId}/question/getlist")
    public ReturnModel getList(@PathVariable(value = "itembankId") String itembankId, @RequestBody FilterModelDto filterModelDto,
                               @RequestParam("isOuter") Boolean isOuter, @RequestParam("isGetContent") Boolean isGetContent) {

        filterModelDto.setItembankId(itembankId);
        return service.getList(filterModelDto, isOuter, isGetContent);
    }
    //endregion

    //region 回收站列表

    /**
     * 回收站列表.
     * 历史接口：
     *
     * @param itembankId     the item bank id
     * @param filterModelDto the map
     * @return the return model
     */
    @PostMapping(value = "/{itembankId}/question/recylebin")
    public ReturnModel getRycleBinList(@PathVariable(value = "itembankId") String itembankId, @RequestBody FilterModelDto filterModelDto) {

        filterModelDto.setItembankId(itembankId);
        return service.getRycleBinList(filterModelDto);
    }
    //endregion

    //region 试题主体修改

    /**
     * Update question return model.
     *
     * @param itembankId    the item bank id
     * @param id            the question id
     * @param questionModel the question model
     * @param appKey        the app key
     * @return the return model
     */
    @PutMapping(value = "/{itembankId}/question/{id}")
    public ReturnModel updateQuestion(@PathVariable(value = "itembankId") String itembankId, @PathVariable(value = "id") String id,
                                      @RequestBody QuestionModel questionModel, @RequestParam("appkey") String appKey) {
        questionModel.setI4(itembankId);

        return service.updateQuestion(itembankId, id, questionModel, appKey);
    }

    //endregion

    //region 试题状态批量修改

    /**
     * 试题状态批量修改
     *
     * @param itembankId  题库id
     * @param statusModel 状态对象
     * @param appKey      appkey
     * @return the return model
     */
    @PutMapping(value = "/{itembankId}/question/status")
    public ReturnModel batchUpdateStatus(@PathVariable(value = "itembankId") String itembankId, @RequestBody UpdateQuestionStatus statusModel,
                                         @RequestParam("appKey") String appKey) {

        return service.batchUpdateStatus(itembankId, statusModel, appKey);
    }

    //endregion

    //region 共享试题

    /**
     * 共享试题.
     *
     * @param sourceItemBankId 源题库id
     * @param chapterRelation  旧新章节对照map
     * @return the return model
     */
    @PutMapping(value = "/{itembankId}/question/share")
    public ReturnModel shareQuestion(@PathVariable(value = "itembankId") String sourceItemBankId,
                                     @RequestParam(value = "targetItemBankID") String targetItemBankID,
                                     @RequestParam(value = "appID") String appID, @RequestParam(value = "orgID") String orgID,
                                     @RequestBody Map<String, String> chapterRelation) {
        CourseItemBank targetItemBank = new CourseItemBank();
        targetItemBank.setItemBankID(targetItemBankID);
        targetItemBank.setCreateOrgID(orgID);
        targetItemBank.setAppID(appID);

        return service.shareQuestion(sourceItemBankId, targetItemBank, chapterRelation);
    }
    //endregion

    //region 试题导入

    /**
     * 试题导入
     *
     * @param itembankId  题库id
     * @param importModel the importModel
     * @return the return model
     */
    @RequestMapping(value = "/{itembankId}/question/import", method = RequestMethod.POST)
    public ReturnModelForTestPaper importQuestion(@PathVariable(value = "itembankId") String itembankId, @RequestBody ImportParameter importModel) throws PoiException {

        return importService.importQuestion(itembankId, importModel);

    }

    /**
     * 试题导入(纯文本)
     *
     * @param itembankId  题库id
     * @param importModel the importModel
     * @return the return model
     */
    @RequestMapping(value = "/{itembankId}/question/importByText", method = RequestMethod.POST)
    public ReturnModelForTestPaper importQuestionByText(@PathVariable(value = "itembankId") String itembankId, @RequestBody ImportParameter importModel) throws PoiException {

        return importService.importQuestion(itembankId, importModel);

    }
    //endregion

    @GetMapping(value = "/{itembankId}/question/esr")
    public ReturnModel getQuestionModel(@PathVariable(value = "id") String itembankId) {

        return service.getQuestionModel(itembankId);
    }
}
